package com.zlj.jdbc.utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Properties;

public class JdbcUtils02<T> {
	private static Properties properties = null;
	private static Connection conn = null;
	private static PreparedStatement pstm = null;
	private static ResultSet resultSet = null;

	private JdbcUtils02() {
		init();
	}

	private void init() {
		try {
			InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
			properties = new Properties();
			properties.load(in);
			Class.forName(properties.getProperty("dirverClassName"));
		} catch (ClassNotFoundException | IOException e) {
			e.printStackTrace();
		}
	}

	private static class LazyLoader {
		private static JdbcUtils02<?> INSTANCE = new JdbcUtils02<>();
	}

	@SuppressWarnings("rawtypes")
	public static JdbcUtils02 getInstance() {
		return LazyLoader.INSTANCE;
	}

	/*
	 * 获取数据库连接
	 */
	public Connection getConnection() {
		if (conn == null) {
			try {
				conn = DriverManager.getConnection(properties.getProperty("jdbcUrl"), properties.getProperty("username"), properties.getProperty("password"));
				return conn;
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} 
		return conn;
	}
	
	/**
	 * 设置参数
	 */
	public void initParams(PreparedStatement pstm, Object... params) {
		for (int i = 0; i < params.length; i++) {
			try {
				pstm.setObject(i + 1, params[i]);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	/*
	 * 执行增删改操作
	 */
	public int update(String sql, Object... params) throws SQLException {
		pstm = conn.prepareStatement(sql);
		initParams(pstm, params);
		int update = pstm.executeUpdate();
		return update;
	}
	
	/**
	 * 执行单笔查询操作
	 * @throws SQLException 
	 */
    public T querySingleResult(String sql, RsHandler<T> rh, Object... params) throws SQLException {
		pstm = conn.prepareStatement(sql);
		initParams(pstm, params);
		resultSet = pstm.executeQuery();
		return rh.handler(resultSet);
    }
    
    /*
     * 查询多笔操作
     */
    public List<T> queryMoreResult(String sql, RsHandler<List<T>> rh, Object... params) throws SQLException {
		pstm = conn.prepareStatement(sql);
		initParams(pstm, params);
		resultSet = pstm.executeQuery();
		return rh.handler(resultSet);
    }
	
	/*
	 * 释放数据库连接
	 */
	public void releaseConnection() {
		try {
			if (resultSet != null) {
				resultSet.close();
			}

			if (pstm != null) {
				pstm.close();
			}

			if (conn != null) {
				conn.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

//用来把结果集转换成需要的类型
interface RsHandler<T> {
	public T handler(ResultSet rs) throws SQLException;
}
